package org.redmagic.bulk;

import java.util.Iterator;
import java.util.Set;

import org.redmagic.api.BulkService;
import org.redmagic.api.HistoryDao;
import org.redmagic.api.PropertyDao;
import org.redmagic.common.Hierarchy;
import org.redmagic.common.MagicProperty;
import org.redmagic.common.MagicRequest;
import org.redmagic.common.MagicResponse;
import org.redmagic.domain.InternalServiceProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.base.Optional;
import com.google.common.collect.Sets;

@Service
public class BulkServiceImpl implements BulkService {

	private static final Logger LOGGER = LoggerFactory.getLogger(BulkServiceImpl.class);
	
	private final PropertyDao propertyDao;
	private final HistoryDao historyDao;
	
	@Autowired
	public BulkServiceImpl(PropertyDao propertyDao, HistoryDao historyDao) {
		this.propertyDao = propertyDao;
		this.historyDao = historyDao;
	}

	@Override
	public MagicResponse resolvePlaceholders(MagicRequest magicRequest, String remoteHost) {
		Set<MagicProperty> resolvedProperties = Sets.newHashSet();
		Hierarchy hierarchy = magicRequest.getHierarchy();
		String group = magicRequest.getGroup();
		
		for (String placeholder : magicRequest.getPlaceholders()) {
			Optional<BulkProperty> magicProperty = resolvePlaceholder(placeholder, hierarchy, group);
			if (magicProperty.isPresent()) {
				resolvedProperties.add(magicProperty.get());
			}
		}
		
		MagicResponse magicResponse = new MagicResponse(resolvedProperties);
		logActivity(magicRequest, magicResponse, remoteHost);
		
		return magicResponse;
	}
	
	private Optional<BulkProperty> resolvePlaceholder(String placeholder, Hierarchy hierarchy, String group) {
		Iterator<Set<String>> tagsIterator = hierarchy.iterator();
		while (tagsIterator.hasNext()) {
			Optional<InternalServiceProperty> magicProperty = propertyDao.findProperty(placeholder, tagsIterator.next(), group);
			if (magicProperty.isPresent()) {
				return Optional.fromNullable(BulkProperty.fromUiProperty(magicProperty.get()));
			}
		}
		return Optional.absent();
	}

	private void logActivity(MagicRequest magicRequest, MagicResponse magicResponse, String remoteHost) {
		LOGGER.info("Logging activity:\nHost: {} \nPlaceholders: {} \nHierarchy: {} \nResolved: {}", 
				remoteHost, magicRequest.getPlaceholders(), magicRequest.getHierarchy(), magicResponse.getResolvedProperties());
		
		historyDao.logActivity(magicRequest, magicResponse, remoteHost);
	}
}
